#include "modelo/Escenario.h"
#include "vista/Vista.h"
#include "SDL/SDL.h"
#include "constantes.h"
#include "modelo/Juego.h"
#include "modelo/Entidad.h"
#include "modelo/Personaje.h"
#include "yaml/Builder.h"
#include "SDL/SDL_image.h"
#include "vista/Formulario.h"
#include <list>
#include <iostream>
#include <string>
#include <exception>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include "red/Server.h"
#include "red/Client.h"
#include "red/ClientSingle.h"
#include "modelo/util/DatosConfiguracion.h"
#include "modelo/util/LoggerConsola.h"
#include <sstream>

int initNetwork();
int server(string escenario);
int client(string nombre, string tipoPersonaje, bool singlePlayer);

int server(string escenario) {
	LoggerConsola logger;
	stringstream ss;
	ss << "EN INICIO DEL SERVER EN DIABLOFIUBA";
	logger.imprimir(&ss, 2);
	int puerto = 1234;
	int puertoChatRecv = 1235;
	int puertoChatSend = 4096;

	string escenarioYaml = "escenarios/" + escenario + ".yaml";
	Builder* unBuilder = new Builder(escenarioYaml);
	ss << "ANTES CREAR JUEGO EN EL SERVER EN DIABLOFIUBA";
	logger.imprimir(&ss, 2);
	Juego *juego = unBuilder->crearJuegoServer();
	// Inicio el server:
	int cantJugadores = 115;
	ss << "INICIA SERVER";
	logger.imprimir(&ss, 2);
	Server server(puerto, juego, unBuilder, cantJugadores, escenarioYaml,
			puertoChatRecv, puertoChatSend);
	cout << "antes server run" << endl;
	server.run();
	cout << "desp server run" << endl;
	delete unBuilder;
	cout << "destruye builder" << endl;
	return 1;
}

/**
 *
 */
int client(string nombre, string tipoPersonaje, string misionSinglePlayer, bool singlePlayer) {
	if (singlePlayer) {
		cout << " es single player" << endl;
		ClientSingle clienteSingle(nombre,tipoPersonaje,misionSinglePlayer);
		clienteSingle.run();
		return 0;
	} else {
		cout << " no es single player" << endl;


		LoggerConsola logger;
		stringstream ss;

		int puertoChatRecv = 1235;
		int puertoChatSend = 4096;
		DatosConfiguracion datosConfiguracion;
		datosConfiguracion.cargarInfoConexion("conexion.txt");
		datosConfiguracion.cargarInfoJugadores("listajugadores.txt");
		ss << "IP: " << datosConfiguracion.getIP() << " Puerto: "
				<< datosConfiguracion.getPuerto();
		logger.imprimir(&ss, 3);
		const char *ip = datosConfiguracion.getIP().c_str();
		int puerto = datosConfiguracion.getPuerto();

		if (!datosConfiguracion.personajeEsSeleccionable(tipoPersonaje)) {
			ss << "EL PERSONAJE NO ES SELECCIONABLE. SALE";
			logger.imprimir(&ss, 3);
			return 0;
		}

		Client client(ip, puerto, puertoChatRecv, puertoChatSend);

		//Client client(ip, puerto);
		client.setNombrePersonaje(nombre);
		client.setTipoPersonaje(tipoPersonaje);
		ss << "CLIENTE CREADO: " << nombre << " TIPO PERSONAJE: "
				<< tipoPersonaje;
		logger.imprimir(&ss, 3);
		int connect = -1;
		connect = client.initConnection();
		if (connect != 0) {

			if (connect == -2) {
				ss << "SERVER LLENO";
				logger.imprimir(&ss, 3);
				client.shutdownConnection();
				return 0;
			} else {
				ss << "ERROR EN LA CONEXION, VERIFIQUE LOS DATOS INGRESADOS";
				logger.imprimir(&ss, 3);
				client.shutdownConnection();
				return 0;
			}
		} else {
			ss << "CONEXION ESTABLECIDA";
			logger.imprimir(&ss, 3);
		}

		ss << "ANTES DE INICIALIZAR CLIENTE";
		logger.imprimir(&ss, 3);
		if (client.inicializarCliente() != 0) {
			ss << "CLIENTE NO INICIALIZADO CORRECTAMENTE";
			logger.imprimir(&ss, 3);
			client.shutdownConnection();
			return 1;
		}

		// El inicializar deja el escenario cargado, listo para comenzar el run del cliente
		logger.imprimir(&ss, 3);
		client.run(ip);
		client.shutdownConnection();
		return 0;
	}
}

/**
 *
 */
int initNetwork() {
	WSADATA t_wsa; // WSADATA structure
	WORD wVers; // version number
	int err; // error number

	wVers = MAKEWORD(2, 2); // Set the version number to 2.2
	err = WSAStartup(wVers, &t_wsa); // Start the WSADATA
	if (err != 0) {
		/* Tell the user that we could not find a usable */
		/* Winsock DLL.                                  */
		printf("WSAStartup failed with error: %d\n", err);
		return 1;
	}
	return 0;
}

int main(int argc, char* argv[]) {
	LoggerConsola logger;
	stringstream ss;
	cout << "EMPEZO EL MAIN" << endl;

	if (initNetwork() == 1) {
		return 1;
	}

	char* tipo = argv[1];
	Formulario* formulario = new Formulario();

    cout << "tipo recibido: " << tipo << endl;

    if (strcmp(tipo, "-server") == 0) {

    	if (argc != 3) {
    		cout << "Parametros invalidos" << endl;
            return 1;
        }
        char* mapa = argv[2];
        server(string(mapa));

    } else if (strcmp(tipo, "-cliente") == 0) {

    	if (argc != 4 && argc!=5) {
    		cout << "Parametros invalidos" << endl;
            return 1;
        }
    	char* nombre = argv[2];
        char* tipo = argv[3];
        char* mision = argv[4];
        if (!formulario->getCerrar()){
    		cout << "Entro al formulario" << endl;
    		formulario->DesplegarSolapaModoJuego();
    		if (formulario->getEsSinglePlayer()) {
    			cout << "Eligio el modo single player" << endl;
    			client(string(nombre),string(tipo),string(mision),true);
    		} else {
    			//Eligio el modo multiplayer
    			client(string(nombre), string(tipo)," ", false);
    		}
        }
        cout << "sale cliente" << endl;
    } else {
            cout << "Parametros invalidos" << endl;
            return 1;
    }

	return 0;
}
